const jsonflatten = {};
jsonflatten.unflatten = function (data, m) {
  "use strict";
  if (Object(data) !== data || Array.isArray(data))
    return data;
  let result = {}, cur, prop, idx, last, temp;
  for (let p in data) {
    cur = result, prop = "", last = 0;
    let pnew = p;
    // JM: 如果flat格式的json是数组，例如 Product.DescriptionData.BulletPoint.0 将变为 prefix=Product.DescriptionData.BulletPoint, suffix=.0
    // Product.Items.0.Age 将变为 prefix=Product.Items, suffix=.0.Age
    // 同时如果d===null, 则表示当前属性不是数组
    const d = /(.+)(\.\d+.*)/.exec(pnew);
    let prefix = null;
    let suffix = null;
    if (d !== null && d.length > 0) {
      prefix = d[1];
      suffix = d[2];
      pnew = prefix;
    }

    if (suffix !== null) {
      if (m !== undefined && m.hasOwnProperty(pnew)) {
        pnew = m[pnew] + suffix;
      } else {
        pnew = pnew + suffix;
      }
    }
    else {
      if (m !== undefined && m.hasOwnProperty(pnew)) {
        pnew = m[pnew];
      }
    }
    do {
      idx = pnew.indexOf(".", last);
      temp = pnew.substring(last, idx !== -1 ? idx : undefined);
      cur = cur[prop] || (cur[prop] = (!isNaN(parseInt(temp)) ? [] : {}));
      prop = temp;
      last = idx + 1;
    } while (idx >= 0);
    cur[prop] = data[p];
  }
  return result[""];
};

jsonflatten.flatten = function (data, m, baseIndex=0) {
  let result = {};

  function recurse(cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur;
    } else if (Array.isArray(cur)) {
      for (let i = 0, l = cur.length; i < l; i++)
        recurse(cur[i], prop ? prop + "." + (i+baseIndex) : "" + (i+baseIndex));
      if (cur.length == 0)
        result[prop] = [];
    } else {
      let isEmpty = true;
      for (let p in cur) {
        isEmpty = false;
        let name_p = p;
        if (m !== undefined && m !== null && m.hasOwnProperty(p)) {
          name_p = m[p];
        }
        const ppp = prop ? prop + "." + name_p : name_p;
        recurse(cur[p], ppp);
      }
      if (isEmpty)
        result[prop] = {};
    }
  }

  recurse(data, "");
  return result;
};

module.exports = jsonflatten;